import pygame
import random
import sys
import tkinter
import time

#定义颜色
WHITE = (255,255,255)
GREEN = (0,255,0)
DARKGREEN = (0,185,0)
YELLOW = (255,255,0)
RED = (255,0,0)

#定义方向
UP = 1
DOWN = 2
LEFT = 3
RIGHT = 4

#定义窗口大小
windowsWidth = 800
windowsHeight = 600

#定义基础单位大小
cellSize = 20

#地图的宽度
mapWidth = int(windowsWidth / cellSize)

#地图的高度
mapHeight = int(windowsHeight / cellSize)

#贪吃蛇头部下标
HEAD = 0

#贪吃蛇的速度
snakeSpeed = 3

starTime = 0




#终止程序
def terminate():
    pygame.quit()
    sys.exit()
    
#移动贪吃蛇
def moveSnake(direction,snakeCoords):
    newHead = {}
    if direction == UP:
        newHead = {"x":snakeCoords[HEAD]["x"],"y":snakeCoords[HEAD]["y"]-1}
    elif direction == DOWN:
        newHead = {"x":snakeCoords[HEAD]["x"],"y":snakeCoords[HEAD]["y"]+1}
    elif direction == LEFT:
        newHead = {"x":snakeCoords[HEAD]["x"]-1,"y":snakeCoords[HEAD]["y"]}
    elif direction == RIGHT:
        newHead = {"x":snakeCoords[HEAD]["x"]+1,"y":snakeCoords[HEAD]["y"]}
        
    snakeCoords.insert(0,newHead)
    

#判断贪吃蛇是否吃到食物
def isEattingFood(snakeCoords,food):
    if snakeCoords[HEAD]["x"] == food["x"] and snakeCoords[HEAD]["y"] == food["y"]:
        food["x"] = random.randint(0,mapWidth - 1)
        food["y"] = random.randint(0,mapHeight - 1)
    else:
        del snakeCoords[-1]
        
        
#判断贪吃蛇是否还活着
def isAlive(snakeCoords):
    tag = True
    if snakeCoords[HEAD]["x"] == -1 or snakeCoords[HEAD]["x"] == mapWidth or snakeCoords[HEAD]["y"] == -1 or snakeCoords[HEAD]["y"] == mapHeight:
        tag = False
    for snake_body in snakeCoords[1:]:
        if snake_body["x"] == snakeCoords[HEAD]["x"] and snake_body["y"] == snakeCoords[HEAD]["y"]:
            tag = False
    return tag


#绘制食物
def drawFood(screen,food):
    x = food["x"] * cellSize
    y = food["y"] * cellSize
    pygame.draw.rect(screen,RED,(x,y,cellSize,cellSize))
    
    
    
#绘制贪吃蛇
def drawSnake(screen,snakeCoords):
    for coord in snakeCoords:
        x = coord["x"] * cellSize
        y = coord["y"] * cellSize
        pygame.draw.rect(screen,DARKGREEN,(x,y,cellSize,cellSize))
        pygame.draw.rect(screen,GREEN,(x+4,y+4,cellSize-8,cellSize-8))
        
        
#绘制分数
def drawScore(screen,score):
    font = pygame.font.SysFont("SimHei",25)
    scoreSurf = font.render(str(score),True,WHITE)
    scoreRect = scoreSurf.get_rect()
    scoreRect.topleft = (320,7)
    screen.blit(scoreSurf,scoreRect)
    
    
#绘制时间
def showTime(screen):
    elap=time.time()-starTime#获取时间差
    minutes = int(elap/60)
    seconds = int(elap-minutes*60.0)
    timeStr = '%02d:%02d' %(minutes, seconds)
  
    
    font = pygame.font.SysFont("SimHei",20)
    timeSurf = font.render(timeStr,True,WHITE)
    timeRect = timeSurf.get_rect()
    timeRect.topleft = (112,10)
    screen.blit(timeSurf,timeRect)
    
    #time.sleep(1)
   
    
 
            
    

#开始游戏
def startGame(screen):
    gameStart = pygame.image.load("snake.jpg")
    screen.blit(gameStart,(144,20))
    
    font = pygame.font.SysFont("SimHei",40)
    tip = font.render("按ENTER键开始游戏",True,(65,105,225))
    screen.blit(tip,(240,550))
    
    pygame.display.update()

    
    while True:
         for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    terminate()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        terminate()
                    elif event.key == pygame.K_RETURN:
                        return    

                    
def runGame(screen,snakeSpeedClock):
    
    startX = random.randint(3,mapWidth-8)
    startY = random.randint(3,mapHeight-8)
    snakeCoords = [{"x":startX,"y":startY},
                   {"x":startX -1,"y":startY},
                   {"x":startX-2,"y":startY}]
    
    direction = RIGHT
    
    food = {"x":random.randint(0,mapWidth -1),"y":random.randint(0,mapHeight -1)}
    global starTime
    global snakeSpeed
    starTime = time.time()
    
    
    while True:
        for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    terminate()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT and direction!=RIGHT:
                        direction = LEFT
                    elif event.key == pygame.K_RIGHT and direction!=LEFT:
                        direction = RIGHT
                    elif event.key == pygame.K_UP and direction!=DOWN:
                        direction = UP
                    elif event.key  == pygame.K_DOWN and direction!=UP:
                        direction = DOWN
                    elif event.key == pygame.K_ESCAPE:
                         terminate()
                    elif event.key == pygame.K_PLUS or  event.key == pygame.K_KP_PLUS:
                        snakeSpeed+=1
                    elif event.key == pygame.K_MINUS or event.key == pygame.K_KP_MINUS:
                        snakeSpeed-=1
                        if snakeSpeed<4:
                            snakeSpeed = 3
        
        moveSnake(direction,snakeCoords)

        isEattingFood(snakeCoords,food)

        ret = isAlive(snakeCoords)
        if not ret:
            break
    
        gameRun = pygame.image.load("background.png")
        screen.blit(gameRun,(0,0))
        
        showTime(screen)
        
        drawFood(screen,food)
        
        drawSnake(screen,snakeCoords)
        
        drawScore(screen,len(snakeCoords) - 3)

        pygame.display.update()
        snakeSpeedClock.tick(snakeSpeed)
    
    
    
def gameOver(screen):
    screen.fill(WHITE)
    gameOver = pygame.image.load("background.png")
    screen.blit(gameOver,(0,0))
    font = pygame.font.SysFont("SimHei",36)
    tip = font.render("按Q或ESC退出游戏，按ENTER键重新开始游戏",True,(65,105,225))
    screen.blit(tip,(50,300))
    pygame.display.update()
    global snakeSpeed
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                terminate()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE or event.key == pygame.K_q:
                    terminate()
                elif event.key == pygame.K_RETURN or event.key == pygame.K_KP_ENTER:
                    snakeSpeed = 3
                    return                       
                
def main():
    pygame.init()
    screen = pygame.display.set_mode((windowsWidth,windowsHeight))
    pygame.display.set_caption("贪吃蛇")
    screen.fill(WHITE)
    snakeSpeedClock = pygame.time.Clock()
    
    startGame(screen)
        
    while True:
        music = pygame.mixer.Sound("pop.wav")
        music.play(-1)
        runGame(screen,snakeSpeedClock)
        music.stop()
        gameOver(screen)
                  
main()
                    
    
    
